using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace SnakeGame
{
    /// <summary>
    /// 游戏渲染器类
    /// </summary>
    public class GameRenderer
    {
        private readonly GameController gameController;
        private readonly Color backgroundColor = Color.Black;
        private readonly Color gridColor = Color.DarkGray;
        private readonly Color snakeHeadColor = Color.LimeGreen;
        private readonly Color snakeBodyColor = Color.LightGreen;
        private readonly Color foodColor = Color.Red;
        private readonly Color wallColor = Color.Gray;

        // 缓存画笔和画刷以提高性能
        private readonly SolidBrush backgroundBrush;
        private readonly SolidBrush snakeHeadBrush;
        private readonly SolidBrush snakeBodyBrush;
        private readonly SolidBrush foodBrush;
        private readonly SolidBrush yellowBrush;
        private readonly Pen gridPen;
        private readonly Pen snakeBorderPen;
        private readonly Pen foodBorderPen;

        // 缓存字体以提高性能
        private readonly Font stateFont;
        private readonly Font pauseFont;
        private readonly Font gameOverFont;
        private readonly Font scoreFont;
        private readonly Font restartFont;

        // 缓存画刷
        private readonly SolidBrush whiteBrush;
        private readonly SolidBrush yellowTextBrush;
        private readonly SolidBrush redBrush;

        public GameRenderer(GameController controller)
        {
            gameController = controller;
            
            // 初始化画笔和画刷
            backgroundBrush = new SolidBrush(backgroundColor);
            snakeHeadBrush = new SolidBrush(snakeHeadColor);
            snakeBodyBrush = new SolidBrush(snakeBodyColor);
            foodBrush = new SolidBrush(foodColor);
            yellowBrush = new SolidBrush(Color.Yellow);
            gridPen = new Pen(gridColor, 1);
            snakeBorderPen = new Pen(Color.DarkGreen, 1);
            foodBorderPen = new Pen(Color.DarkRed, 2);

            // 初始化字体
            stateFont = new Font("微软雅黑", 12, FontStyle.Bold);
            pauseFont = new Font("微软雅黑", 24, FontStyle.Bold);
            gameOverFont = new Font("微软雅黑", 28, FontStyle.Bold);
            scoreFont = new Font("微软雅黑", 16, FontStyle.Regular);
            restartFont = new Font("微软雅黑", 12, FontStyle.Regular);

            // 初始化文本画刷
            whiteBrush = new SolidBrush(Color.White);
            yellowTextBrush = new SolidBrush(Color.Yellow);
            redBrush = new SolidBrush(Color.Red);
        }

        /// <summary>
        /// 绘制游戏
        /// </summary>
        public void Draw(Graphics g, Rectangle gameArea)
        {
            // 设置高质量渲染
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            // 绘制背景
            DrawBackground(g, gameArea);

            // 绘制网格（可选）
            if (ShowGrid)
            {
                DrawGrid(g, gameArea);
            }

            // 绘制蛇
            DrawSnake(g, gameArea);

            // 绘制食物
            DrawFood(g, gameArea);

            // 绘制游戏状态信息
            DrawGameInfo(g, gameArea);
        }

        /// <summary>
        /// 绘制背景
        /// </summary>
        private void DrawBackground(Graphics g, Rectangle gameArea)
        {
            g.FillRectangle(backgroundBrush, gameArea);
        }

        /// <summary>
        /// 绘制网格
        /// </summary>
        private void DrawGrid(Graphics g, Rectangle gameArea)
        {
            int cellSize = gameController.Config.CellSize;

            // 绘制垂直线
            for (int x = 0; x <= gameController.Config.GameWidth; x++)
            {
                int pixelX = gameArea.X + x * cellSize;
                g.DrawLine(gridPen, pixelX, gameArea.Y, pixelX, gameArea.Bottom);
            }

            // 绘制水平线
            for (int y = 0; y <= gameController.Config.GameHeight; y++)
            {
                int pixelY = gameArea.Y + y * cellSize;
                g.DrawLine(gridPen, gameArea.X, pixelY, gameArea.Right, pixelY);
            }
        }

        /// <summary>
        /// 绘制蛇
        /// </summary>
        private void DrawSnake(Graphics g, Rectangle gameArea)
        {
            int cellSize = gameController.Config.CellSize;

            foreach (var node in gameController.Snake.Body)
            {
                Rectangle cellRect = new Rectangle(
                    gameArea.X + node.Position.X * cellSize,
                    gameArea.Y + node.Position.Y * cellSize,
                    cellSize,
                    cellSize
                );

                // 绘制蛇身
                if (node.IsHead)
                {
                    g.FillRectangle(snakeHeadBrush, cellRect);
                }
                else
                {
                    g.FillRectangle(snakeBodyBrush, cellRect);
                }

                // 绘制边框
                g.DrawRectangle(snakeBorderPen, cellRect);

                // 如果是蛇头，绘制眼睛
                if (node.IsHead)
                {
                    DrawSnakeEyes(g, cellRect, gameController.Snake.Direction);
                }
            }
        }

        /// <summary>
        /// 绘制蛇的眼睛
        /// </summary>
        private void DrawSnakeEyes(Graphics g, Rectangle cellRect, Direction direction)
        {
            using (var brush = new SolidBrush(Color.Black))
            {
                int eyeSize = cellRect.Width / 6;
                int eyeOffset = cellRect.Width / 4;

                Point leftEye, rightEye;

                switch (direction)
                {
                    case Direction.Up:
                        leftEye = new Point(cellRect.X + eyeOffset, cellRect.Y + eyeOffset);
                        rightEye = new Point(cellRect.Right - eyeOffset - eyeSize, cellRect.Y + eyeOffset);
                        break;
                    case Direction.Down:
                        leftEye = new Point(cellRect.X + eyeOffset, cellRect.Bottom - eyeOffset - eyeSize);
                        rightEye = new Point(cellRect.Right - eyeOffset - eyeSize, cellRect.Bottom - eyeOffset - eyeSize);
                        break;
                    case Direction.Left:
                        leftEye = new Point(cellRect.X + eyeOffset, cellRect.Y + eyeOffset);
                        rightEye = new Point(cellRect.X + eyeOffset, cellRect.Bottom - eyeOffset - eyeSize);
                        break;
                    case Direction.Right:
                        leftEye = new Point(cellRect.Right - eyeOffset - eyeSize, cellRect.Y + eyeOffset);
                        rightEye = new Point(cellRect.Right - eyeOffset - eyeSize, cellRect.Bottom - eyeOffset - eyeSize);
                        break;
                    default:
                        return;
                }

                g.FillEllipse(brush, leftEye.X, leftEye.Y, eyeSize, eyeSize);
                g.FillEllipse(brush, rightEye.X, rightEye.Y, eyeSize, eyeSize);
            }
        }

        /// <summary>
        /// 绘制食物
        /// </summary>
        private void DrawFood(Graphics g, Rectangle gameArea)
        {
            if (!gameController.Food.IsVisible)
                return;

            int cellSize = gameController.Config.CellSize;
            Rectangle foodRect = new Rectangle(
                gameArea.X + gameController.Food.Position.X * cellSize,
                gameArea.Y + gameController.Food.Position.Y * cellSize,
                cellSize,
                cellSize
            );

            // 绘制食物（圆形）
            g.FillEllipse(foodBrush, foodRect);

            // 绘制食物边框
            g.DrawEllipse(foodBorderPen, foodRect);

            // 添加闪烁效果
            if (DateTime.Now.Millisecond < 500)
            {
                g.FillEllipse(yellowBrush, foodRect.X + 2, foodRect.Y + 2, foodRect.Width - 4, foodRect.Height - 4);
            }
        }

        /// <summary>
        /// 绘制游戏信息
        /// </summary>
        private void DrawGameInfo(Graphics g, Rectangle gameArea)
        {
            // 绘制游戏状态
            string stateText = gameController.GetGameStateText();
            SizeF textSize = g.MeasureString(stateText, stateFont);
            PointF textPoint = new PointF(
                gameArea.X + (gameArea.Width - textSize.Width) / 2,
                gameArea.Y + 10
            );
            g.DrawString(stateText, stateFont, whiteBrush, textPoint);

            // 如果游戏暂停，绘制暂停提示
            if (gameController.State == GameState.Paused)
            {
                DrawPauseOverlay(g, gameArea);
            }

            // 如果游戏结束，绘制游戏结束提示
            if (gameController.State == GameState.GameOver)
            {
                DrawGameOverOverlay(g, gameArea);
            }
        }

        /// <summary>
        /// 绘制暂停覆盖层
        /// </summary>
        private void DrawPauseOverlay(Graphics g, Rectangle gameArea)
        {
            // 半透明背景
            using (var brush = new SolidBrush(Color.FromArgb(128, 0, 0, 0)))
            {
                g.FillRectangle(brush, gameArea);
            }

            // 暂停文字
            string pauseText = "游戏暂停";
            SizeF textSize = g.MeasureString(pauseText, pauseFont);
            PointF textPoint = new PointF(
                gameArea.X + (gameArea.Width - textSize.Width) / 2,
                gameArea.Y + (gameArea.Height - textSize.Height) / 2
            );
            g.DrawString(pauseText, pauseFont, yellowTextBrush, textPoint);
        }

        /// <summary>
        /// 绘制游戏结束覆盖层
        /// </summary>
        private void DrawGameOverOverlay(Graphics g, Rectangle gameArea)
        {
            // 半透明背景
            using (var brush = new SolidBrush(Color.FromArgb(180, 0, 0, 0)))
            {
                g.FillRectangle(brush, gameArea);
            }

            // 游戏结束文字
            string gameOverText = "游戏结束";
            SizeF textSize = g.MeasureString(gameOverText, gameOverFont);
            PointF textPoint = new PointF(
                gameArea.X + (gameArea.Width - textSize.Width) / 2,
                gameArea.Y + (gameArea.Height - textSize.Height) / 2 - 30
            );
            g.DrawString(gameOverText, gameOverFont, redBrush, textPoint);

            // 最终得分
            string scoreText = $"最终得分: {gameController.CurrentScore}";
            textSize = g.MeasureString(scoreText, scoreFont);
            textPoint = new PointF(
                gameArea.X + (gameArea.Width - textSize.Width) / 2,
                gameArea.Y + (gameArea.Height - textSize.Height) / 2 + 10
            );
            g.DrawString(scoreText, scoreFont, whiteBrush, textPoint);

            // 重新开始提示
            string restartText = "按 R 键重新开始";
            textSize = g.MeasureString(restartText, restartFont);
            textPoint = new PointF(
                gameArea.X + (gameArea.Width - textSize.Width) / 2,
                gameArea.Y + (gameArea.Height - textSize.Height) / 2 + 50
            );
            g.DrawString(restartText, restartFont, yellowTextBrush, textPoint);
        }

        /// <summary>
        /// 是否显示网格
        /// </summary>
        public bool ShowGrid { get; set; } = false;

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            backgroundBrush?.Dispose();
            snakeHeadBrush?.Dispose();
            snakeBodyBrush?.Dispose();
            foodBrush?.Dispose();
            yellowBrush?.Dispose();
            gridPen?.Dispose();
            snakeBorderPen?.Dispose();
            foodBorderPen?.Dispose();
            
            stateFont?.Dispose();
            pauseFont?.Dispose();
            gameOverFont?.Dispose();
            scoreFont?.Dispose();
            restartFont?.Dispose();
            
            whiteBrush?.Dispose();
            yellowTextBrush?.Dispose();
            redBrush?.Dispose();
        }
    }
} 